package com.ys.day32.p2注解的深入应用;

import jdk.nashorn.internal.ir.CallNode;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 描述:
 *
 * @author CodeYang
 * @version 2021/1/18 17:31
 */
public class JSON {


    public static  String parseSimpleToString(Object obj){
        StringBuilder sb = new StringBuilder(30);
        sb.append("{");

        Class<?> aClass = obj.getClass();
        // 1获得Fileds
        Field[] fields = aClass.getDeclaredFields();
        int index = 0;
        try {
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            //暴力破解属性
            field.setAccessible(true);
            String key = field.getName();
            Object value = field.get(obj);

            // 判断一下 key 上有没有 忽略注解 JSONIgnore
            if (field.isAnnotationPresent(JSONIgnore.class)){
                // 如果有的话,那么跳过这个属性
                continue;
            }
            // 在这里,证明已经是 没有被 JSONIgnore 修饰的属性
            // 判断一下是否存在 注解配置别名
            if (field.isAnnotationPresent(JSONFiled.class)){
                //如果有 把key值更新为 注解配置的别名
                JSONFiled jsonFiled = field.getDeclaredAnnotation(JSONFiled.class);
                key = jsonFiled.value();

            }
            // 判断一下 是否是时间格式的数据|
            // instanceof 可以判断是否为null值的情况,如果是空值返回false
            if (value instanceof Date){

                //判断该字段是否被 时间注解格式化了
                if (field.isAnnotationPresent(FormatDateFile.class)){
                    //如果是的 时间类型的 数据,取出 指定的 str 来格式化 date
                    // 取出注解
                    FormatDateFile formatDateFile = field.getDeclaredAnnotation(FormatDateFile.class);
                    String patter = formatDateFile.patter();
                    SimpleDateFormat sdf = new SimpleDateFormat(patter);
                    value= sdf.format(value);
                }
            }
            // 1 判断一下是不是第一个 key:value对象
            if (0 == i) {
                sb.append("\"" + key + "\"" + ":" + isFormatCheckObjectType(value));
            } else {
                sb.append(",\"" + key + "\"" + ":" + isFormatCheckObjectType(value));
            }

        }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        return sb.append("}").toString();
    }

    /**
     * 用于检查传递进来的对象的数据类型,
     * 预设返回应该只有4种与 json的规则一致
     * 1: number 数字
     * *  2: str
     * *  3; boolean
     * *  4; null
     * 思路 : 使用 instanceof 来判断类型(包装类),
     * 但是 insranceof 只能用来判断包装类,也就是我们这里还处理不了其 实体类字段为普通类型的情况
     * 扩展: 可以在判断之前做一次转换
     *
     * @param obj
     * @return Type
     */
    private static Object isFormatCheckObjectType(Object obj) {

        Object type = null;
        if (obj instanceof Number) {
            type = obj;
        } else if (obj instanceof Boolean) {
            return obj;
        } else if (null == obj) {
            type = "null";
        } else if (obj instanceof String) {
            type = "\"" + obj + "\"";
        } else {
            // 不是这4种类型就转为 str 来拼接
            type = "\"" + obj + "\"";
            //throw new  RuntimeException("参数转换超出范围");
        }
        return type;
    }
}
